using AvaMaid.Messages;
using CommunityToolkit.Mvvm.Messaging;
using DebounceThrottle;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using WK.Libraries.SharpClipboardNS;

namespace AvaMaid.Views
{
    /// <summary>
    /// CodeGenViewUserControl.xaml 的交互逻辑
    /// </summary>
    public partial class CodeGenViewUserControl : UserControl,IRecipient<ClassDomainLoadedEventArgs>
    {
        private DebounceDispatcher _dispatcher = new DebounceDispatcher(200);
        private DebounceDispatcher _clipboardDispatcher = new DebounceDispatcher(200);
        private SharpClipboard _sharpClipboard = new SharpClipboard();

        public CodeGenViewUserControl()
        {
            InitializeComponent();

            var tbs = new[] { PART_ClassTB, PART_PropertyTypeTB, PART_PropertyNameTB };

            foreach (var t in tbs)
            {
                t.TextChanged += T_TextChanged;
            }

            Clipboard.Clear();
            //_sharpClipboard.ClipboardChanged += _sharpClipboard_ClipboardChanged;
            //App.Current.Exit += Current_Exit;

            WeakReferenceMessenger.Default.Register(this);

        }

        private void Current_Exit(object sender, ExitEventArgs e)
        {
            _sharpClipboard.ClipboardChanged -= _sharpClipboard_ClipboardChanged;
            _sharpClipboard.Dispose();
        }

        private void _sharpClipboard_ClipboardChanged(object sender, SharpClipboard.ClipboardChangedEventArgs e)
        {
            if (e.ContentType != SharpClipboard.ContentTypes.Text) return;
            if (e.Content is string == false) return;
            var clipbardArgs = e.Content as string;
            if (string.IsNullOrWhiteSpace(clipbardArgs)) return;
            //MessageBox.Show(clipbardArgs);
            _clipboardDispatcher.Debounce(() => { AnalyzeClipbardArgs(clipbardArgs); });

        }

        private void AnalyzeClipbardArgs(string clipboardArgs)
        {

        }

        private void T_TextChanged(object sender, TextChangedEventArgs e)
        {
            UpdateCode();
        }

        private void UpdateCode()
        {
            _dispatcher.Debounce(() =>
            {
                Application.Current.Dispatcher.Invoke(() =>
                {
                    GeneratePropertyCode(PART_ClassTB.Text, PART_PropertyTypeTB.Text, PART_PropertyNameTB.Text);
                });
            });
        }

        private void GeneratePropertyCode(string ownerClass, string propertyType, string propertyName)
        {

            PART_DPText.Text = GetDPCode(ownerClass, propertyType, propertyName);
            PART_APText.Text = GetAPCode(ownerClass, propertyType, propertyName);
        }

        private string GetDPCode(string ownerClass, string propertyType, string propertyName)
        {
            var dpTemplate =
$@"public static readonly StyledProperty<{propertyType}> {propertyName}Property = AvaloniaProperty.Register<{ownerClass}, {propertyType}>(nameof({propertyName}));
public {propertyType} {propertyName} {{get =>({propertyType})GetValue({propertyName}Property); set =>SetValue({propertyName}Property, value);}}";

            return dpTemplate;
        }

        private string GetAPCode(string ownerClass, string propertyType, string propertyName)
        {
            var apTemplate =
$@"public static readonly AttachedProperty<{propertyType}> {propertyName}Property = AvaloniaProperty.RegisterAttached<{ownerClass}, Control, {propertyType}> (""{propertyName}"");
public static {propertyType} Get{propertyName}(Control element) =>({propertyType})element.GetValue({propertyName}Property);
public static void Set{propertyName}(Control element, {propertyType} value) => element.SetValue({propertyName}Property, value);";
            return apTemplate;
        }

        private void PART_DPCopyButton_Click(object sender, RoutedEventArgs e)
        {
            Clipboard.SetText(PART_DPText.Text);
        }

        private void PART_APCopyButton_Click(object sender, RoutedEventArgs e)
        {
            Clipboard.SetText(PART_APText.Text);
        }

        void IRecipient<ClassDomainLoadedEventArgs>.Receive(ClassDomainLoadedEventArgs message)
        {
            if (message == null) return;
            if (message.ClassDomain == null) return;

            Application.Current.Dispatcher.Invoke(() =>
            {
                var classDomain = message.ClassDomain;
                PART_ClassTB.Text = classDomain.ClassName;
                PART_PropertyTypeTB.Text = classDomain.MemberType;
                PART_PropertyNameTB.Text = classDomain.MemberName;
            });

        }
    }
}
